/*
 * Copyright (C) 2010-2011 Comcast Cable.  All Rights Reserved.
 */
package com.hercules.android.receiver.handlers.commands.call.animation.interpolators;

import android.view.animation.Interpolator;

/**
 * This class is the base class for all the interpolator classes provided by current component. It stores the in and out
 * flags which are used to identify whether the functionality is "ease in", "ease out" or "ease in and out". It
 * implements Interpolator interface.
 * <p>
 * <b>Thread Safety:</b> This class is immutable and thread-safe.
 *
 * @author semi_sleep, 7realm
 * @version 1.0
 */
public abstract class BaseInterpolator implements Interpolator {
    /**
     * Represents the in flag used to determine whether the current interpolator should provide "ease in" motion, if
     * both in and out flags are true, current interpolator should provide "ease in and out" motion.
     * <p>
     * Can be any value, cannot be false when the out flag is false. It's initialized by constructor, and cannot be
     * changed after that. It has a protected getter to expose it to subclasses.
     */
    private final boolean in;

    /**
     * Represents the out flag used to determine whether the current interpolator should provide "ease out" motion, if
     * both in and out flags are true, current interpolator should provide "ease in and out" motion.
     * <p>
     * Can be any value, cannot be false when the in flag is false. It's initialized by constructor, and cannot be
     * changed after that. It has a protected getter to expose it to subclasses.
     */
    private final boolean out;

    /**
     * Creates an instance of BaseInterpolator using the given in and out flag.
     *
     * @param in the flag indicates whether "ease in" motion should be provided
     * @param out the flag indicates whether "ease out" motion should be provided
     * @throws IllegalArgumentException if both in and out flags are false
     */
    public BaseInterpolator(boolean in, boolean out) {
        // check arguments
        if (!in && !out) {
            throw new IllegalArgumentException("Both 'in' and 'out' flags cannot be false at same time.");
        }

        // assign values
        this.in = in;
        this.out = out;
    }

    /**
     * Gets the in flag.
     *
     * @return the in flag
     */
    protected boolean isIn() {
        return in;
    }

    /**
     * Gets the out flag.
     *
     * @return the out flag
     */
    protected boolean isOut() {
        return out;
    }

    /**
     * Checks if input is in [0, 1] range.
     *
     * @param input the float value to check
     * @throws IllegalArgumentException if input is not in [0, 1]
     */
    static void checkRange(float input) {
        if (input < 0 || input > 1) {
            throw new IllegalArgumentException("Argument 'input' must be in [0, 1] range.");
        }
    }
}